/* This program was designed to generate a Cyberlink PowerDirector 10
 * Picture-in-Picture path for a very quick shake.  The result is a
 * .cpt (custom path) file with a randomized path with a different
 * location each frame.
 *
 * Unfortunately, I've forgotten how to import the path, so your best
 * bet is probably to simply use my "arrow shake" PiP object on the
 * DirectorZone.  This code is more for anyone who wants to try and
 * generate their own .cpt files, as the file format is pretty
 * wonky. */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>

using namespace std;

float centerXArr[] = { 0.272895, 0.277095, 0.282119, 0.292748, 0.313933, 0.317680, 0.318655, 0.319540, 0.321816, 0.323881, 0.328299, 0.340201, 0.340921, 0.341083, 0.342104, 0.349016, 0.353435, 0.354551, 0.368571, 0.374776, 0.374959, 0.375049, 0.375141, 0.375232, 0.375324, 0.375415, 0.375505, 0.375779, 0.386375, 0.393296, 0.396985 };

float centerYArr[] = { 0.419071, 0.436348, 0.446959, 0.457464, 0.457555, 0.457919, 0.458101, 0.458192, 0.458374, 0.458555, 0.464762, 0.469883, 0.472760, 0.475642, 0.485771, 0.488150, 0.490217, 0.494509, 0.494623, 0.496324, 0.496649, 0.496710, 0.497062, 0.499642, 0.505583, 0.515626, 0.515805, 0.517077, 0.520928, 0.520941, 0.542263, 0.542718, 0.559919, 0.574818 };

float heightArr[] = { 1.070476, 1.082888, 1.083070, 1.083252, 1.083434, 1.083616, 1.083798, 1.083980, 1.084162, 1.084344, 1.084526, 1.084708, 1.084890, 1.085072, 1.085254, 1.085436, 1.085618, 1.101642, 1.105999, 1.106083, 1.119837, 1.119867, 1.119897, 1.119927, 1.127303, 1.141901, 1.149637, 1.161858, 1.161999 };

float widthArr[] = { 0.802857, 0.812165, 0.812302, 0.812438, 0.812575, 0.812712, 0.812849, 0.812985, 0.813121, 0.813258, 0.813395, 0.813532, 0.813669, 0.813806, 0.813942, 0.814079, 0.814215, 0.826231, 0.829499, 0.829562, 0.839878, 0.839900, 0.839922, 0.839944, 0.845478, 0.856425, 0.862228, 0.871392, 0.871498 };

class Settings
{
public:
   Settings()
   {
      uint16_t index;
      int fd = open("/dev/urandom", O_RDONLY);
      if (fd != -1)
      {
         read(fd, (void*)&index, sizeof(index));
         centerX = centerXArr[index % (sizeof(centerXArr) / sizeof(*centerXArr))];
         read(fd, (void*)&index, sizeof(index));
         centerY = centerYArr[index % (sizeof(centerYArr) / sizeof(*centerYArr))];
         read(fd, (void*)&index, sizeof(index));
         height = heightArr[index % (sizeof(heightArr) / sizeof(*heightArr))];
         read(fd, (void*)&index, sizeof(index));
         width = widthArr[index % (sizeof(widthArr) / sizeof(*widthArr))];
         close(fd);
      }
   }
   float centerX, centerY, height, width;
};


int main(int argc, char *argv[])
{
      // 261 frames; = 8s 21 frames
   const unsigned numFrames = 261;
   ostringstream s;
   vector <Settings> saveSet;

   saveSet.resize(numFrames+1);

   s << "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" << "\r\n"
     << "<CPicture Version=\"6.000000\">"
     << "<Header>"
     << "<Information Creator=\"CPicture Exported XML\"/>"
     << "<Extension ReferencePath=\"C:\\Program Files (x86)\\CyberLink\\templates\\PowerDirector Content Pack 10\\PowerDirector 10 Content Pack II\\PiPObject\\PinP_002_16_9\\\"/>"
     << "</Header>"
     << "<PictureList>"
     << "<MetaPicture Version=\"6.000000\" PosType=\"0\" Interpolation=\"2\" PiPMemoryUsage=\"2\">"
     << "<S3DList>"
     << "<MetaS3D DistanceType=\"0\" DepthLowerBound=\"-0.333333\" DepthUpperBound=\"0.333333\"/>"
     << "</S3DList>"
     << "<SourceList>"
     << "<MetaSource Type=\"1\" FileName=\"dummy\" ImageStereoMode=\"0\" UseAlpha=\"true\" S3DSourceMode=\"0\" SrcFixed=\"true\" SrcAspectRatioX=\"4\" SrcAspectRatioY=\"3\" SrcStretchMode=\"0\" DrawFlipType=\"0\" ShowShadowBorderColorKey=\"true\" Subtype=\"0\"/>"
     << "</SourceList>"
     << "<SourceRegionList/>"
     << "<ShapeList>"
     << "<MetaShape ChromaKey_Version=\"0.000000\" EnableColorKey=\"false\" ColorKey=\"0\" ColorKeyRange=\"38\" ColorKeyRangeH=\"10\" ColorKeyCoordinateX=\"-1\" ColorKeyCoordinateY=\"-1\" MaskFile=\"\" MaskStretchMode=\"0\" MaskStretchFactorX0=\"0.000000\" MaskStretchFactorX1=\"1.000000\" MaskStretchFactorY0=\"0.000000\" MaskStretchFactorY1=\"1.000000\" MaskStretchBGAlpha=\"0\"/>"
     << "</ShapeList>"
     << "<FaceList>"
     << "<MetaFace Enable=\"true\" Alpha=\"255\" BlurRadius=\"0\" EnableBlendingColor=\"false\" BlendingColor=\"16777215\"/>"
     << "</FaceList>"
     << "<BorderList>"
     << "<MetaBorder Enable=\"false\" Size=\"3\" Color1=\"0\" Color2=\"0\" GradType=\"0\" Alpha=\"255\" BlurRadius=\"0\" BorderType=\"1\" ValueType=\"0\"/>"
     << "</BorderList>"
     << "<ShadowList>"
     << "<MetaShadow EnableShape=\"false\" EnableBorder=\"false\" Color1=\"0\" Color2=\"0\" GradType=\"0\" Alpha=\"255\" BlurRadius=\"0\" OffsetX=\"0.000000\" OffsetY=\"-0.000000\" Height=\"false\" OffsetS3Ddepth=\"0.000000\"/>"
     << "</ShadowList>"
     << "<Position1List>"
     << "<MetaPosition1 CenterX=\"0.433156\" CenterY=\"0.490217\" Width=\"0.845478\" Height=\"1.127303\" Degree=\"0.000000\" Alpha=\"255\" TangentVectorX1=\"0.000000\" TangentVectorY1=\"0.000000\" TangentVectorX2=\"0.000000\" TangentVectorY2=\"0.000000\" EnableS3Ddepth=\"0\" S3Ddepth=\"0.000000\"/>"
     << "</Position1List>"
     << "<PositionList>"
     << "<MetaPosition X1=\"0.000000\" Y1=\"0.000000\" X2=\"1.000000\" Y2=\"0.000000\" X3=\"1.000000\" Y3=\"1.000000\" X4=\"0.000000\" Y4=\"1.000000\" Width=\"0.845478\" Height=\"1.127303\" Degree=\"0.000000\" Alpha=\"255\" CenterX=\"0.433156\" CenterY=\"0.490217\" TangentVectorX1=\"0.000000\" TangentVectorY1=\"0.000000\" TangentVectorX2=\"0.000000\" TangentVectorY2=\"0.000000\" RectCenterX=\"0.000000\" RectCenterY=\"0.000000\" EnableS3Ddepth=\"0\" S3Ddepth=\"0.000000\"/>"
     << "</PositionList>"
     << "<Motion1List>";

      // generate motion list here
      // Keyframe is a % offset from 0 to 1.
   for (unsigned i = 0; i <= numFrames; i++)
   {
      saveSet[i] = Settings();
      s << "<MetaMotion1 Index=\"" << (i+1) << "\" Keyframe=\""
        << fixed << setw(8) << setprecision(6) << ((float)i / numFrames)
        << "\" CenterX=\"" << saveSet[i].centerX
        << "\" CenterY=\"" << saveSet[i].centerY
        << "\" Width=\"" << saveSet[i].width
        << "\" Height=\"" << saveSet[i].height
        << "\" Degree=\"0.000000\" Alpha=\"255\""
        << " TangentVectorX1=\"0.000000\" TangentVectorY1=\"0.000000\""
        << " TangentVectorX2=\"0.000000\" TangentVectorY2=\"0.000000\""
        << " EnableS3Ddepth=\"0\" S3Ddepth=\"0.000000\"/>";
   }

   s << "</Motion1List>"
     << "<MotionList>";

      // generate motion list here
   for (unsigned i = 0; i <= numFrames; i++)
   {
      s << "<MetaMotion Index=\"" << (i+1) << "\" Keyframe=\""
        << fixed << setw(8) << setprecision(6) << ((float)i / numFrames)
        << "\" CenterX=\"" << saveSet[i].centerX
        << "\" CenterY=\"" << saveSet[i].centerY
        << "\" X1=\"0.000000\" Y1=\"0.000000\" X2=\"1.000000\" Y2=\"0.000000\""
        << " X3=\"1.000000\" Y3=\"1.000000\" X4=\"0.000000\" Y4=\"1.000000\""
        << " Width=\"" << saveSet[i].width
        << "\" Height=\"" << saveSet[i].height
        << "\" RectCenterX=\"0.000000\""
        << " RectCenterY=\"0.000000\" Degree=\"0.000000\" Alpha=\"255\""
        << " TangentVectorX1=\"0.000000\" TangentVectorY1=\"0.000000\""
        << " TangentVectorX2=\"0.000000\" TangentVectorY2=\"0.000000\""
        << " EnableS3Ddepth=\"0\" S3Ddepth=\"0.000000\"/>";
   }

   s << "</MotionList>"
     << "<OutputList>"
     << "<MetaOutput OutputAspectRatioX=\"576\" OutputAspectRatioY=\"324\" OutputQuality=\"0\" WorkingMode=\"0\" Source=\"0\" UseSourceAlpha=\"1\" ScreenDiagonal=\"20\" ScreenAspectRationX=\"16\" ScreenAspectRationY=\"9\"/>"
     << "</OutputList>"
     << "</MetaPicture>"
     << "</PictureList>"
     << "<State FullState=\"0\"/>"
     << "</CPicture>" << "\r\n";

   string moo(s.str());
      // file starts with 0xff 0xff and then each character has a null
      // after it.  Weird, but whatever.
   unsigned char a(0xff), b(0xfe), nil(0);
   cout << a << b;
   for (unsigned i = 0; i < moo.length(); i++)
   {
      cout << moo[i] << nil;
   }

   return 0;
}
